package gminet.infra.toolkit;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

/**
 * @author: Gabriel Flores Mendes
 */
public final class DateToolkit {

    private static final String TIME_ZONE = "GMT-3:00";

    private static final Locale LOCALE = new Locale("pt", "br");

    private static DateFormat dateFormat;

    private static DateFormat timeFormat;

    private static DateFormat dateTimeFormat;

    /**
     * ConversorToolkit constructor comment.
     */
    private DateToolkit() {
        super();
    }

    public static Date getDate() {

        Date braDate = null;
        Calendar foreignCalendar = new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE));
        foreignCalendar.setTimeInMillis(new Date().getTime());
        String hour = StringToolkit.leftNumber(foreignCalendar.get(Calendar.HOUR_OF_DAY), 2);
        String minute = StringToolkit.leftNumber(foreignCalendar.get(Calendar.MINUTE), 2);
        String second = StringToolkit.leftNumber(foreignCalendar.get(Calendar.SECOND), 2);
        String date = StringToolkit.leftNumber(foreignCalendar.get(Calendar.DATE), 2);
        String month = StringToolkit.leftNumber(foreignCalendar.get(Calendar.MONTH) + 1, 2);
        String year = String.valueOf(foreignCalendar.get(Calendar.YEAR));
        String strDate = date + "/" + month + "/" + year + " " + hour + ":" + minute + ":" + second;
        try {
            braDate = getDateTimeFormat().parse(strDate);
        } catch (Exception e) {
            throw new RuntimeException("Invalid date (DateToolkit.getDate(), " + strDate + ")");
        }
        return braDate;
    }

    public static Date getDateFromString(String strDate) {
        try {
            if (StringToolkit.isFill(strDate)) {
                byte[] newDate = strDate.getBytes();
                for (int i = 0; i < newDate.length; i++) {
                    switch (newDate[i]) {
                    case '\\':
                    case '-':
                    case '.':
                        newDate[i] = (byte) '/';
                    }
                }
                return getDateFormat().parse(new String(newDate));
            } else {
                return null;
            }
        } catch (ParseException pe) {
            return null;
        }
    }

    public static Date getTimeFromString(String strTime) {

        try {
            if (StringToolkit.isFill(strTime)) {
                int separator = 0;
                for (int i = strTime.length() - 1; i != -1; i--) {
                    if (strTime.charAt(i) == ':') {
                        separator++;
                    }
                }
                while (separator < 3) {
                    strTime += ":00";
                    separator++;
                }
                Date hour = getTimeFormat().parse(strTime);
                return hour;
            } else {
                return null;
            }
        } catch (ParseException e) {
            throw new RuntimeException("Invalid time (" + strTime + ")");
        }
    }

    public static Date getDateTimeFromString(String strDateTime) {

        try {
            return getDateTimeFormat().parse(strDateTime);
        } catch (ParseException re) {
            throw new RuntimeException("Invalid date time (" + strDateTime + ")");
        }
    }

    public static String getStringFromDateTime(java.util.Date dateTime) {
        return getStringFromDateTime(dateTime, false);
    }

    public static String getStringFromDateTime(java.util.Date dateTime, boolean notNull) {
        return getStringFromDate(dateTime, notNull) + " " + getStringFromTime(dateTime, notNull);
    }

    public static String getStringFromDate(java.util.Date date) {
        return getStringFromDate(date, false);
    }

    public static String getStringFromDate(java.util.Date date, boolean notNull) {

        String strDate = notNull ? "" : null;
        if (date != null) {
            strDate = getDateFormat().format(date);
        }
        return strDate;
    }

    public static String getStringFromTime(java.util.Date time) {
        return getStringFromTime(time, false);
    }

    public static String getStringFromTime(java.util.Date time, boolean notNull) {

        String strTime = notNull ? "" : null;
        if (time != null) {
            strTime = getTimeFormat().format(time);
        }
        return strTime;
    }

    public static Date addDay(Date date, int days) {

        Date newDate = null;
        if (date != null) {
            long time = date.getTime();
            time += days * (24 * 60 * 60 * 1 * 1000);
            newDate = new Date(time);
        }
        return newDate;
    }

    public static int getHour(Date date) {

        int hour = 0;
        if (date != null) {
            String str = getStringFromTime(date);
            if (StringToolkit.isFill(str)) {
                str = str.substring(0, 2);
                hour = NumberToolkit.getIntFromString(str.trim());
            }
        }
        return hour;
    }

    private static DateFormat getTimeFormat() {
        if (timeFormat == null) {
            timeFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM, LOCALE);
            timeFormat.setLenient(false);
        }
        return timeFormat;
    }

    private static DateFormat getDateFormat() {
        if (dateFormat == null) {
            dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, LOCALE);
            dateFormat.setLenient(false);
        }
        return dateFormat;
    }

    private static DateFormat getDateTimeFormat() {
        if (dateTimeFormat == null) {
            dateTimeFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        }
        return dateTimeFormat;
    }

}
